package com.aliyun.heiyu.powermaster.server.service;

import com.aliyun.heiyu.common.util.*;
import com.aliyun.heiyu.powermaster.proto.*;
import com.aliyun.heiyu.powermaster.server.Error;
import com.aliyun.heiyu.powermaster.server.dao.AiDataProviderDao;
import com.aliyun.heiyu.powermaster.server.dao.QosCollectInfoDao;
import com.aliyun.heiyu.powermaster.server.dao.entity.AiDataEntity;
import com.aliyun.heiyu.powermaster.server.dao.entity.DeviceCommonEntity;
import com.aliyun.heiyu.powermaster.server.dao.entity.StrategyActionEntity;
import com.aliyun.heiyu.powermaster.server.dao.impl.AiDataProviderDaoImpl;
import com.aliyun.heiyu.powermaster.server.dao.impl.QosCollectInfoImpl;
import com.aliyun.heiyu.powermaster.server.dao.impl.StrategyActionImpl;
import com.aliyun.heiyu.powermaster.server.factory.MasterThreadFactory;
import com.aliyun.heiyu.powermaster.server.factory.TransDeviceManager;
import com.aliyun.heiyu.powermaster.server.manager.*;
import com.aliyun.heiyu.powermaster.server.rotary.dao.RecommendDAO;
import com.aliyun.heiyu.powermaster.server.rotary.dao.impl.RecommendDAOImpl;
import com.aliyun.heiyu.powermaster.server.rotary.object.entity.RecommendEntity;
import com.aliyun.heiyu.powermaster.server.rotary.service.AirService;
import com.aliyun.heiyu.powermaster.server.rotary.service.impl.AirServiceImpl;
import com.aliyun.heiyu.powermaster.server.util.Configuration;
import com.aliyun.heiyu.powermaster.server.util.ZkClientUtil;
import org.apache.http.client.utils.URIBuilder;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.net.URI;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class AiDataProviderImpl implements AiDataProvider {
    private static Logger logger = LoggerFactory.getLogger(AiDataProviderImpl.class);
    private static String ip = Configuration.IP;

    private AiDataProviderDao aiDataProviderDao;
    private QosManager qosManager;
    private DeviceManager deviceManager;
    private ThunderManager thunderManager;
    private WarningService warningService;
    private QosCollectInfoDao qosCollectInfoDao;
    private StrategyManager strategyManager;
    private PowerDataService powerDataService;
    private AirService airService;
    private String aiIp;
    private long diffMax;
    private RecommendDAO recommendDAO;

    public AiDataProviderImpl() {
        recommendDAO = new RecommendDAOImpl();
        this.deviceManager = TransDeviceManager.getDeviceServiceTrans();
        this.aiDataProviderDao = new AiDataProviderDaoImpl();
        this.thunderManager = new ThunderManagerImpl();
        this.qosManager = QosManagerImpl.getInstance();
        this.warningService = new WarningServiceImpl();
        this.qosCollectInfoDao = new QosCollectInfoImpl();
        this.strategyManager = StrategyManager.getInstance();
        this.powerDataService = new PowerDataServiceImpl();
        this.airService = new AirServiceImpl();
        this.aiIp = PropertiesUtil.getValue("serverIp.properties", "aiIp");
        this.diffMax = Long.valueOf(PropertiesUtil.getValue("serverIp.properties", "diffTimeMax"));
        if (StringUtil.isEmpty(aiIp)) {
            this.aiIp = "localhost";
        }
        jobTime();
    }

    private int count = 0;
    private int deteTime = 5;
    private int cfdcoef = Integer.valueOf(PropertiesUtil.getValue("serverIp.properties","cfdCoef"));


    //定时间隔15分钟ai预测温度并存库
    void jobTime() {
        final Calendar instance = Calendar.getInstance();
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(1, 1,
            60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new MasterThreadFactory("AI"));
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (ZkClientUtil.checkLeader()) {
                        Date date = new Date();
                        instance.setTime(date);

                        //获取当前分钟数
                        //时间5分钟查一次  定义个count判断是不是15  是执行 不是判断推荐温度是不是比设置小

                        int time = instance.get(Calendar.MINUTE);
                        //判断当前分钟为整15间隔
                        if (time % deteTime == 0) {
                            int num = 1;
                            count++;
                            //获取最新控制力度
                            Map<String, String> currentOne = aiDataProviderDao.findCurrentOne();
                            if (null != currentOne && currentOne.size() !=0) {
                                String control_status = currentOne.get("control_status");
                                if (!StringUtil.isEmpty(control_status)) {
                                    num = Integer.valueOf(control_status);
                                }
                            }
                            //获取上次历史温度推荐温度
                            double reference_temp = 0.0;
                            AiDataEntity lastHistoryData = aiDataProviderDao.findLastHistoryData();
                            if (null == lastHistoryData) {
                                reference_temp = 25.0;
                            } else {
                                reference_temp = Double.valueOf(lastHistoryData.getReference_temp());
                            }
                            AiDataEntity entity = new AiDataEntity();
                            List<String> ips = new ArrayList();
                            List<String> powers = new ArrayList();
                            //算法工具类
                            LRUtil util = new LRUtil();
                            Map<String, String> currentAirTempCollectInfo = aiDataProviderDao.findCurrentAirTempCollectInfo();
                            //当前温度,查不到为默认
                            double currentTemp = 21.0;
                            //预测温度初始值
                            double initialTemp = 17.0;
                            //预测温度
                            double intelligentTemp = 0;
                            //控制力度低对应的阈值
                            double low = 0.3;
                            //控制力度中对应的阈值
                            double mid = 0.5;
                            //控制力度高对应的阈值
                            double high = 0.7;
                            //定义节约功率变量
                            double intelligentPower = 0;
                            //定义cooling系数集合
                            List<Double> cooling = new ArrayList();

                            List<Double> results = new ArrayList();
                            //定义系数数组
                            Double[] coef = {1.4161, 1.7122, 2.5910, 1.6774, 0.0, 0.3868, 0.0, 0.0, -3.2876, 0.0, -5.1526, 0.0, 0.0};
                            //添加cooling系数，代表预测计算温度，初始为17，cooling为1代表预测计算温度为17+8*1
                            cooling.add(1.0);
                            cooling.add(0.9375);
                            cooling.add(0.875);
                            cooling.add(0.8125);
                            cooling.add(0.75);
                            cooling.add(0.6875);
                            cooling.add(0.625);
                            cooling.add(0.5625);
                            cooling.add(0.5);
                            cooling.add(0.4375);
                            cooling.add(0.375);
                            cooling.add(0.3125);
                            cooling.add(0.25);
                            cooling.add(0.1875);
                            cooling.add(0.125);
                            cooling.add(0.0625);
                            cooling.add(0.0);
                            entity.setCurrent_temp(currentTemp);
                            //获取所有设备ip及对应功耗
                            Map<String, String> map = getAIPower();
                            Set<String> strings = map.keySet();
                            for (int i = 0; i < cooling.size(); i++) {
                                List<Double> list = new ArrayList();
                                list.add(cooling.get(i));
                                for (String str : strings) {
                                    list.add(Double.valueOf(map.get(str)) / 1000);
                                }
                                //获取当前cooling系数的计算系数数组
                                Double[] arr = list.toArray(new Double[list.size()]);
                                //调用算法util计算，并将结果添加到结果集中
                                results.add(util.getSig(coef, arr));
                            }
                            //获取当前计算的ips和powers
                            for (String str : strings) {
                                ips.add(str);
                                powers.add(map.get(str));
                            }
                            //判断当前控制力度状态，0，1，2，3对应无，低，中，高
                            if (1 == num) {
                                for (int i = 0; i < results.size(); i++) {
                                    if (results.get(i) < low) {
                                        BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                                        BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                                        BigDecimal ctemp = new BigDecimal(Double.toString(currentTemp));
                                        intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                                        intelligentPower = new BigDecimal("1.83").multiply(new BigDecimal(Double.toString(intelligentTemp)).subtract(ctemp)).doubleValue();
                                        if (intelligentPower < 0) {
                                            intelligentPower = 0;
                                        }
                                        if (intelligentTemp < currentTemp) {
                                            intelligentTemp = currentTemp;
                                        }
                                        entity.setReference_temp(String.valueOf(intelligentTemp));
                                        entity.setRisk_value(results.get(i));
                                        break;
                                    } else {
                                        if (i == results.size() - 1) {
                                            BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                                            BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                                            intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                                            if (intelligentTemp < currentTemp) {
                                                intelligentTemp = currentTemp;
                                            }
                                            entity.setReference_temp(String.valueOf(intelligentTemp));
                                            entity.setRisk_value(results.get(i));
                                        }

                                    }
                                }
                                entity.setControl_status(num);
                            }
                            if (2 == num) {
                                for (int i = 0; i < results.size(); i++) {
                                    if (results.get(i) < mid) {
                                        BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                                        BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                                        BigDecimal ctemp = new BigDecimal(Double.toString(currentTemp));
                                        intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                                        intelligentPower = new BigDecimal("1.83").multiply(new BigDecimal(Double.toString(intelligentTemp)).subtract(ctemp)).doubleValue();
                                        if (intelligentPower < 0) {
                                            intelligentPower = 0;
                                        }
                                        if (intelligentTemp < currentTemp) {
                                            intelligentTemp = currentTemp;
                                        }
                                        entity.setReference_temp(String.valueOf(intelligentTemp));
                                        entity.setRisk_value(results.get(i));
                                        break;
                                    } else {
                                        if (i == results.size() - 1) {
                                            BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                                            BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                                            intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                                            if (intelligentTemp < currentTemp) {
                                                intelligentTemp = currentTemp;
                                            }
                                            entity.setReference_temp(String.valueOf(intelligentTemp));
                                            entity.setRisk_value(results.get(i));
                                        }

                                    }
                                }
                                entity.setControl_status(num);
                            }
                            if (3 == num) {
                                for (int i = 0; i < results.size(); i++) {
                                    if (results.get(i) < high) {
                                        BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                                        BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                                        BigDecimal ctemp = new BigDecimal(Double.toString(currentTemp));
                                        intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                                        intelligentPower = new BigDecimal("1.83").multiply(new BigDecimal(Double.toString(intelligentTemp)).subtract(ctemp)).doubleValue();
                                        if (intelligentPower < 0) {
                                            intelligentPower = 0;
                                        }
                                        if (intelligentTemp < currentTemp) {
                                            intelligentTemp = currentTemp;
                                        }
                                        entity.setReference_temp(String.valueOf(intelligentTemp));
                                        entity.setRisk_value(results.get(i));
                                        break;
                                    } else {
                                        if (i == results.size() - 1) {
                                            BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                                            BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                                            intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                                            if (intelligentTemp < currentTemp) {
                                                intelligentTemp = currentTemp;
                                            }
                                            entity.setReference_temp(String.valueOf(intelligentTemp));
                                            entity.setRisk_value(results.get(i));
                                        }
                                    }
                                }
                                entity.setControl_status(num);
                            }

                            if (0 == num) {
                                entity.setReference_temp(String.valueOf(currentTemp));
                                entity.setControl_status(num);
                                entity.setRisk_value(0);
                            }
                            entity.setIp(ips.toString());
                            entity.setPower(powers.toString());
                            entity.setCollect_time(date);
                            //添加到历史数据表中
                            if (StringUtil.convertDouble(entity.getReference_temp()) < reference_temp) {
                                aiDataProviderDao.insertHistory(entity);
                                count = 0;
                            } else {
                                if (3 == count) {
                                    aiDataProviderDao.insertHistory(entity);
                                    count = 0;
                                }
                            }

                            try {
                                Thread.sleep(180 * 1000);
                            } catch (InterruptedException e) {
                                logger.error(e.getMessage(), e);
                            }
                        }
                    }
                }
            }
        });
    }


    @Override
    public Map<String, String> getAIPower() {
        Map<String, String> map = new HashMap<>();
        String server_power = "";
        String ip = "";
        String server_sn = "";
        //获取所有服务器
        Map<String, PowerInfo> serverPowerInfos = thunderManager.getAllServerPowerInfo();
        if (null == serverPowerInfos || serverPowerInfos.size() == 0) {
            return map;
        }
        ArrayList<PowerInfo> powerInfos = new ArrayList<>(serverPowerInfos.values());
        //获取服务器ip及当前功耗，并封装到map中
        for (int i = 0; i < powerInfos.size(); i++) {
            server_sn = powerInfos.get(i).getEquipmentNumber();
            if (null == server_sn || server_sn.isEmpty()) {
                continue;
            }
            DeviceCommonEntity oneDeviceCommon = deviceManager.findOneDeviceCommon(server_sn);
            if (null != oneDeviceCommon) {
                ip = oneDeviceCommon.getIp();
            }

            if (null == ip || ip.isEmpty()) {
                continue;
            }
            server_power = String.valueOf(powerInfos.get(i).getServerPower());
            map.put(ip, server_power);
        }
        return map;
    }

    @Override
    public GetAiTempReply getAITemp(int num) {
        if (num < 0) {
            num = 0;
        }
        GetAiTempReply.Builder builder = GetAiTempReply.newBuilder();
        //算法工具类
        LRUtil util = new LRUtil();
        //当前温度,查不到为默认
        Map<String, String> currentAirTempCollectInfo = aiDataProviderDao.findCurrentAirTempCollectInfo();
        double currentTemp = 21.0;
        if (null != currentAirTempCollectInfo && currentAirTempCollectInfo.size() != 0) {
            String roomTemperature = currentAirTempCollectInfo.get("room_temperature");
            if (!StringUtil.isEmpty(roomTemperature)) {
                currentTemp = Double.valueOf(roomTemperature);
            }
        }
        builder.setModelCoef("1.4161, 1.7122, 2.5910, 1.6774, 0.0, 0.3868, 0.0, 0.0, -3.2876, 0.0, -5.1526, 0.0, 0.0");

        //预测温度初始值
        double initialTemp = 17.0;
        //预测温度
        double intelligentTemp = 0;
        //控制力度低对应的阈值
        double low = 0.4;
        //控制力度中对应的阈值
        double mid = 0.7;
        //控制力度高对应的阈值
        double high = 0.9;
        //定义节约功率变量
        double intelligentPower = 0;
        //定义cooling系数集合
        List<Double> cooling = new ArrayList();

        List<Double> results = new ArrayList();
        //定义系数数组
        //Double[] coef = {1.4161, 1.7122, 2.5910, 1.6774, 0.0, 0.3868, 0.0, 0.0, -3.2876, 0.0, -5.1526, 0.0, 0.0};
        Double[] coef = {0.4161, 0.7122, 0.5910, 0.6774, 0.0, 0.3868, 0.0, 0.0, -3.2876, 0.0, -5.1526, 0.0, 0.0};
        //添加cooling系数，代表预测计算温度，初始为17，cooling为1代表预测计算温度为17+8*1
        cooling.add(1.0);
        cooling.add(0.9375);
        cooling.add(0.875);
        cooling.add(0.8125);
        cooling.add(0.75);
        cooling.add(0.6875);
        cooling.add(0.625);
        cooling.add(0.5625);
        cooling.add(0.5);
        cooling.add(0.4375);
        cooling.add(0.375);
        cooling.add(0.3125);
        cooling.add(0.25);
        cooling.add(0.1875);
        cooling.add(0.125);
        cooling.add(0.0625);
        cooling.add(0.0);
        Map<String, String> map = getAIPower();
        if (null == map || map.size() == 0) {
            return builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(currentTemp)).setIntelligentPower(intelligentPower).setControlStatus(num)).build();
        }
        Set<String> strings = map.keySet();
        for (int i = 0; i < cooling.size(); i++) {
            List<Double> list = new ArrayList();
            list.add(cooling.get(i));
            for (String str : strings) {
                list.add(Double.valueOf(map.get(str)) / 1000);
            }
            //获取当前cooling系数的计算系数数组
            Double[] arr = list.toArray(new Double[list.size()]);
            //调用算法util计算，并将结果添加到结果集中
            results.add(util.getSig(coef, arr));
        }
        //调用动环策略方法进行策略下发
        try {
            airService.strategy(num);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //判断当前控制力度状态，0，1，2，3对应无，低，中，高，并添加实时数据
        if (1 == num) {
            for (int i = 0; i < results.size(); i++) {
                if (results.get(i) < low) {
                    BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                    BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                    BigDecimal ctemp = new BigDecimal(Double.toString(currentTemp));
                    intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                    intelligentPower = new BigDecimal("1.83").multiply(new BigDecimal(Double.toString(intelligentTemp)).subtract(ctemp)).doubleValue();
                    if (intelligentPower < 0) {
                        intelligentPower = 0;
                    }
                    if (intelligentTemp < currentTemp) {
                        intelligentTemp = currentTemp;
                    }
                    aiDataProviderDao.insert(new Date(), currentTemp, intelligentTemp, num, Double.valueOf(new DecimalFormat("#.00").format(intelligentPower)), results.get(i));
                    builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(intelligentTemp)).setControlStatus(num).setIntelligentPower(Double.valueOf(new DecimalFormat("#.00").format(intelligentPower))).build());
                    return builder.build();
                } else {
                    if (i == results.size() - 1) {
                        BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                        BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                        intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                        if (intelligentTemp < currentTemp) {
                            intelligentTemp = currentTemp;
                        }
                        aiDataProviderDao.insert(new Date(), currentTemp, intelligentTemp, num, Double.valueOf(new DecimalFormat("#.00").format(intelligentPower)), results.get(i));
                        builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(currentTemp)).setControlStatus(num).setIntelligentPower(intelligentPower).build());
                        return builder.build();
                    }
                }
            }
        }
        if (2 == num) {
            for (int i = 0; i < results.size(); i++) {
                if (results.get(i) < mid) {
                    BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                    BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                    BigDecimal ctemp = new BigDecimal(Double.toString(currentTemp));
                    intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                    intelligentPower = new BigDecimal("1.83").multiply(new BigDecimal(Double.toString(intelligentTemp)).subtract(ctemp)).doubleValue();
                    if (intelligentPower < 0) {
                        intelligentPower = 0;
                    }
                    if (intelligentTemp < currentTemp) {
                        intelligentTemp = currentTemp;
                    }
                    aiDataProviderDao.insert(new Date(), currentTemp, intelligentTemp, num, Double.valueOf(new DecimalFormat("#.00").format(intelligentPower)), results.get(i));
                    builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(intelligentTemp)).setControlStatus(num).setIntelligentPower(Double.valueOf(new DecimalFormat("#.00").format(intelligentPower))).build());
                    return builder.build();
                } else {
                    if (i == results.size() - 1) {
                        BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                        BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                        intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                        if (intelligentTemp < currentTemp) {
                            intelligentTemp = currentTemp;
                        }
                        aiDataProviderDao.insert(new Date(), currentTemp, intelligentTemp, num, Double.valueOf(new DecimalFormat("#.00").format(intelligentPower)), results.get(i));
                        builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(intelligentTemp)).setControlStatus(num).setIntelligentPower(intelligentPower).build());
                        return builder.build();
                    }
                }
            }
        }
        if (3 == num) {
            for (int i = 0; i < results.size(); i++) {
                if (results.get(i) < high) {
                    BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                    BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                    BigDecimal ctemp = new BigDecimal(Double.toString(currentTemp));
                    intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                    intelligentPower = new BigDecimal("1.83").multiply(new BigDecimal(Double.toString(intelligentTemp)).subtract(ctemp)).doubleValue();
                    if (intelligentPower < 0) {
                        intelligentPower = 0;
                    }
                    if (intelligentTemp < currentTemp) {
                        intelligentTemp = currentTemp;
                    }
                    aiDataProviderDao.insert(new Date(), currentTemp, intelligentTemp, num, Double.valueOf(new DecimalFormat("#.00").format(intelligentPower)), results.get(i));
                    builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(intelligentTemp)).setControlStatus(num).setIntelligentPower(Double.valueOf(new DecimalFormat("#.00").format(intelligentPower))).build());
                    return builder.build();

                } else {
                    if (i == results.size() - 1) {
                        BigDecimal itemp = new BigDecimal(Double.toString(initialTemp));
                        BigDecimal cool = new BigDecimal(Double.toString(cooling.get(i)));
                        intelligentTemp = itemp.add(cool.multiply(new BigDecimal("8"))).doubleValue();
                        if (intelligentTemp < currentTemp) {
                            intelligentTemp = currentTemp;
                        }
                        aiDataProviderDao.insert(new Date(), currentTemp, intelligentTemp, num, Double.valueOf(new DecimalFormat("#.00").format(intelligentPower)), results.get(i));
                        builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(intelligentTemp)).setControlStatus(num).setIntelligentPower(intelligentPower).build());
                        return builder.build();
                    }
                }
            }
        }
        if (0 == num) {
            aiDataProviderDao.insert(new Date(), currentTemp, intelligentTemp, num, intelligentPower, 0);
            builder.setData(AiTemp.newBuilder().setCurrentTemp(currentTemp).setIntelligentTemp(String.valueOf(currentTemp)).setIntelligentPower(intelligentPower).setControlStatus(num).build());
            return builder.build();
        }

        return builder.build();
    }


    @Override
    public GetTempHistoryReply getTempHistory(String startTime, String endTime) {
        GetTempHistoryReply.Builder builder = GetTempHistoryReply.newBuilder();
        AiTempHistoryData.Builder builder1 = AiTempHistoryData.newBuilder();
        //根据起止时间查询条件数据集
        List<AiDataEntity> list = aiDataProviderDao.findByTime(startTime, endTime);
        for (int i = 0; i < list.size(); i++) {
            AiDataEntity entity = list.get(i);
            if(StringUtil.isEmpty(entity.getReference_temp())){
                continue;
            }
            double referenceTemp = Double.valueOf(entity.getReference_temp());
            if (referenceTemp < entity.getCurrent_temp()) {
                referenceTemp = entity.getCurrent_temp();
            }
            builder.addData(builder1.setCollectTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(entity.getCollect_time())).setControlStatus(entity.getControl_status())
                .setCurrentTemp(entity.getCurrent_temp()).setIntelligentTemp(referenceTemp));
        }
        return builder.build();
    }


    @Override
    public GetAiTempReply getLastAiTemp() {
        GetAiTempReply.Builder builder = GetAiTempReply.newBuilder();
        //查询最新数据
        RecommendEntity recommendEntity = recommendDAO.queryRecommendNew();
       if(null == recommendEntity){
           return builder.setErrCode(Error.SUCCESS.getCode()).setErrMsg(Error.SUCCESS.getMessage()).build();
       }
       //获取节省功率
        //获取最新控制力度并进行新计算返回
        //当前温度
        double current_temp = recommendEntity.getCurrent_temp();
        double recommend_temp = recommendEntity.getRecommend_temp();
        //推荐温度
        if(current_temp > recommend_temp){
            recommend_temp = current_temp;
        }
        double intelligentPower = new BigDecimal("1.83").multiply(new BigDecimal(recommend_temp).subtract(new BigDecimal(current_temp))).doubleValue();
        return builder.setData(AiTemp.newBuilder().setCurrentTemp(current_temp).setIntelligentTemp(String.valueOf(recommend_temp)).setIntelligentPower(intelligentPower).build()).build();
    }


    private String millisecondToDate(Long millisecond) {
        Date date = new Date(millisecond);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(date);
    }

    private long dateToMillisecond(String dateTime) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateTime));
        } catch (java.text.ParseException e) {
            e.printStackTrace();
        }
        return calendar.getTimeInMillis();
    }


    //计算策略下设备功耗
    private Map<String, Integer> getStrategyPower(int num, String sn) {
        Map<String, Integer> map = new HashMap<>();
        BigDecimal unloadedCase1 = new BigDecimal(345);
        BigDecimal unloadedCase2 = new BigDecimal(216);
        BigDecimal unloadedCase3 = new BigDecimal(173);
        BigDecimal halfLoadCase1 = new BigDecimal(425);
        BigDecimal halfLoadCase2 = new BigDecimal(368);
        BigDecimal halfLoadCase3 = new BigDecimal(342);
        BigDecimal fullLoadCase1 = new BigDecimal(503);
        BigDecimal fullLoadCase2 = new BigDecimal(503);
        BigDecimal fullLoadCase3 = new BigDecimal(504);
        BigDecimal defaultPower = new BigDecimal(170);
        int estimatePower = 0;
        int savePower = 0;

        if (num < 0) {
            num = 0;
        }
        //获取当前设备数据
        PowerInfo powerInfo1 = thunderManager.getPowerInfo(sn);

        if (null == powerInfo1) {
            logger.error("当前设备不存在或者设备编号输入错误");
            return map;
        }
        int currentPower = powerInfo1.getServerPower();
        double cpuUsage = powerInfo1.getCpuUsage();

        if (0 == num) {
            estimatePower = currentPower;
            map.put("currentPower", currentPower);
            map.put("savePower", savePower);
            map.put("estimatePower", estimatePower);
            return map;
        }
        if (1 == num) {
            if (cpuUsage >= 0 && cpuUsage < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else if (cpuUsage >= 20 && cpuUsage < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            }
        }

        if (2 == num) {
            if (cpuUsage >= 0 && cpuUsage < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else if (cpuUsage >= 20 && cpuUsage < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            }
        }

        if (3 == num) {
            if (cpuUsage >= 0 && cpuUsage < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;

            } else if (cpuUsage >= 20 && cpuUsage < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            }
        }
        return map;
    }

    @Override
//todo 事务
    public GetAiPowerReply getAiCurrentPower(int num) {
        GetAiPowerReply.Builder builder = GetAiPowerReply.newBuilder();
        BigDecimal unloadedCase1 = new BigDecimal(345);
        BigDecimal unloadedCase2 = new BigDecimal(216);
        BigDecimal unloadedCase3 = new BigDecimal(173);
        BigDecimal halfLoadCase1 = new BigDecimal(425);
        BigDecimal halfLoadCase2 = new BigDecimal(368);
        BigDecimal halfLoadCase3 = new BigDecimal(342);
        BigDecimal fullLoadCase1 = new BigDecimal(503);
        BigDecimal fullLoadCase2 = new BigDecimal(503);
        BigDecimal fullLoadCase3 = new BigDecimal(504);
        BigDecimal defaultPower = new BigDecimal(170);
        int currentPower = 0;
        int estimatePower = 0;
        int savePower = 0;

        if (num < 0) {
            num = 0;
        }
        Map<String, PowerInfo> serverPowerInfos = thunderManager.getAllServerPowerInfo();
        if (null == serverPowerInfos  || serverPowerInfos.size() == 0) {
            return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
        }
        HashMap<String, String> cpuMap = new HashMap<>();
        List<BigDecimal> list = new ArrayList<BigDecimal>();
        Set<String> keys = serverPowerInfos.keySet();
        for (String key : keys) {
            PowerInfo powerInfo = serverPowerInfos.get(key);
            String cpu_usage = String.valueOf(powerInfo.getCpuUsage());
            String server_power = String.valueOf(powerInfo.getServerPower());
            if (StringUtil.isEmpty(cpu_usage)) {
                continue;
            }
            if (StringUtil.isEmpty(server_power)) {
                continue;
            }
            BigDecimal power = new BigDecimal(server_power);
            BigDecimal cpu = new BigDecimal(cpu_usage);
            int i = power.intValue();
            currentPower += i;
            list.add(cpu);
        }

        double avg = getAvg(list);
        if (0 == num) {
            estimatePower = currentPower;
            aiDataProviderDao.insertPowerStatus(num);
            updateStrategyAction(num);
            return builder.setData(AiPower.newBuilder().setCurrentPower(currentPower).setEstimatePower(estimatePower).setSavePower(0).setControlStatus(num).build()).build();
        }

        if (1 == num) {
            aiDataProviderDao.insertPowerStatus(num);
            updateStrategyAction(num);
            if (avg >= 0 && avg < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            } else if (avg >= 20 && avg < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            }
        }

        if (2 == num) {
            aiDataProviderDao.insertPowerStatus(num);
            updateStrategyAction(num);
            if (avg >= 0 && avg < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            } else if (avg >= 20 && avg < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            }
        }

        if (3 == num) {
            aiDataProviderDao.insertPowerStatus(num);
            updateStrategyAction(num);
            if (avg >= 0 && avg < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            } else if (avg >= 20 && avg < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                return builder.setData(AiPower.newBuilder().setControlStatus(num).setSavePower(savePower).setEstimatePower(estimatePower).setCurrentPower(currentPower).build()).build();
            }
        }
        return builder.build();
    }

    @Override
    public GetAiPowerReply getLastAiPower() {
        GetAiPowerReply.Builder builder = GetAiPowerReply.newBuilder();

        Map<String, String> map = aiDataProviderDao.findCurrentPowerStatus();
        if (null == map || map.isEmpty() || map.size() == 0) {
            return builder.build();
        }
        int control_status = Integer.valueOf(map.get("control_status"));
        GetAiPowerReply aiPower = getAiCurrentPower(control_status);
        return aiPower;
    }

    //计算当前策略下设备历史总功耗
    private Map<String, Integer> getStrategyPowerHistory(int num, int currentPower, double cpuUsage) {
        Map<String, Integer> map = new HashMap<>();

        BigDecimal unloadedCase1 = new BigDecimal(345);
        BigDecimal unloadedCase2 = new BigDecimal(216);
        BigDecimal unloadedCase3 = new BigDecimal(173);
        BigDecimal halfLoadCase1 = new BigDecimal(425);
        BigDecimal halfLoadCase2 = new BigDecimal(368);
        BigDecimal halfLoadCase3 = new BigDecimal(342);
        BigDecimal fullLoadCase1 = new BigDecimal(503);
        BigDecimal fullLoadCase2 = new BigDecimal(503);
        BigDecimal fullLoadCase3 = new BigDecimal(504);
        BigDecimal defaultPower = new BigDecimal(170);
        int estimatePower = 0;
        int savePower = 0;

        if (num < 0) {
            num = 0;
        }

        if (0 == num) {
            estimatePower = currentPower;
            map.put("currentPower", currentPower);
            map.put("savePower", savePower);
            map.put("estimatePower", estimatePower);
            return map;
        }
        if (1 == num) {
            if (cpuUsage >= 0 && cpuUsage < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else if (cpuUsage >= 20 && cpuUsage < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase1, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            }
        }

        if (2 == num) {
            if (cpuUsage >= 0 && cpuUsage < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else if (cpuUsage >= 20 && cpuUsage < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            }
        }
        if (3 == num) {
            if (cpuUsage >= 0 && cpuUsage < 20) {
                BigDecimal divide = unloadedCase2.divide(unloadedCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;

            } else if (cpuUsage >= 20 && cpuUsage < 80) {
                BigDecimal divide = halfLoadCase2.divide(halfLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            } else {
                BigDecimal divide = fullLoadCase2.divide(fullLoadCase3, 2, BigDecimal.ROUND_UP);
                estimatePower = divide.multiply(BigDecimal.valueOf(currentPower)).add(defaultPower).intValue();
                savePower = estimatePower - currentPower;
                if (savePower < 0) {
                    savePower = 0;
                }
                map.put("currentPower", currentPower);
                map.put("savePower", savePower);
                map.put("estimatePower", estimatePower);
                return map;
            }
        }
        return map;
    }


    @Override
    public GetAiPowerReply getAiStrategiesPower(String strategy) {
        GetAiPowerReply.Builder builder = GetAiPowerReply.newBuilder();
        int currentPowerSum = 0;
        int savePowerSum = 0;
        int estimatePowerSum = 0;
        //获取所有打开的字段策略列表
        List<StrategyDetail> allAutoStrategiesOfOn = strategyManager.getAllAutoStrategiesOfOn();
        if (null == allAutoStrategiesOfOn || allAutoStrategiesOfOn.size() == 0) {
            return builder.build();
        }
        //遍历策略列表，获取策略名称和控制力度
        for (StrategyDetail strategyDetail : allAutoStrategiesOfOn) {
            //判断策略名称
            if (!strategy.equals(strategyDetail.getStrategyName())) {
                continue;
            }
            String controlLevel = strategyDetail.getControlLevel();
            //判断控制力度
            if (!StringUtil.isEmpty(controlLevel)) {
                //策略下获取设备列表
                List<DeviceInfo> deviceInfosList = strategyDetail.getDeviceInfosList();
                if (null == deviceInfosList || deviceInfosList.size() == 0) {
                    continue;
                }
                //遍历设备列表获取设备信息
                for (DeviceInfo deviceInfo : deviceInfosList) {
                    String equipmentNumber = deviceInfo.getEquipmentNumber();
                    Map<String, Integer> strategyPowerMap = getStrategyPower(Integer.valueOf(controlLevel), equipmentNumber);
                    if (null == strategyPowerMap || strategyPowerMap.size() == 0) {
                        logger.error("当前设备数据错误" + equipmentNumber);
                        continue;
                    }
                    currentPowerSum += strategyPowerMap.get("currentPower");
                    savePowerSum += strategyPowerMap.get("savePower");
                    estimatePowerSum += strategyPowerMap.get("estimatePower");
                }
            }
        }

        return builder.setData(AiPower.newBuilder().setCurrentPower(currentPowerSum).setEstimatePower(estimatePowerSum).setSavePower(savePowerSum).build()).build();
    }

    @Override
    public GetAiPowerReply getAiPower() {
        GetAiPowerReply.Builder builder = GetAiPowerReply.newBuilder();
        int currentPowerSum = 0;
        int savePowerSum = 0;
        //获取所有设备功耗
        Map<String, PowerInfo> serverPowerInfos = thunderManager.getAllServerPowerInfo();
        if (null == serverPowerInfos || serverPowerInfos.isEmpty() || serverPowerInfos.size() == 0) {
            return builder.setErrMsg("data error").build();
        }
        Set<String> keys = serverPowerInfos.keySet();
        //遍历获取所有设备总功耗
        for (String key : keys) {
            PowerInfo powerInfo = serverPowerInfos.get(key);
            String server_power = String.valueOf(powerInfo.getServerPower());
            if (null == server_power || server_power.isEmpty()) {
                continue;
            }
            BigDecimal power = new BigDecimal(server_power);
            int i = power.intValue();
            currentPowerSum += i;
        }
        //获取所有策略
        List<StrategyDetail> allAutoStrategiesOfOn = strategyManager.getAllAutoStrategiesOfOn();
        //计算未优化总功耗
        for (StrategyDetail strategyDetail : allAutoStrategiesOfOn) {
            String strategyName = strategyDetail.getStrategyName();
            savePowerSum += getAiStrategiesPower(strategyName).getData().getSavePower();
        }
        int estimatePowerSum = currentPowerSum + savePowerSum;
        return builder.setData(AiPower.newBuilder().setSavePower(savePowerSum).setEstimatePower(estimatePowerSum).setCurrentPower(currentPowerSum).build()).build();
    }


    //计算策略下设备历史功耗方法
    private List<Map<String, String>> getSum(List<DeviceInfo> deviceInfos, String startTime, String endTime, int level) {
        List<Map<String, String>> restultList = new ArrayList<>();
        List<List<PowerInfo>> list = new ArrayList<>();
        List<PowerInfo> powerInfoList = null;
        int size = 0;
        //遍历所有设备获取设备编号，
        for (int i = 0; i < deviceInfos.size(); i++) {
            String equipmentNumber = deviceInfos.get(i).getEquipmentNumber();
            List<PowerInfo> powerInfos = powerDataService.getPowerForAi(equipmentNumber, startTime, endTime, 0).getDataList().get(0).getInfosList();
            size = powerInfos.size();
            list.add(powerInfos);
            powerInfoList = new ArrayList<>(powerInfos);
        }
        //遍历数据进行计算
        for (int i = 0; i < size; i++) {
            int currentPowerSum = 0;
            int savePowerSum = 0;
            int estimatePowerSum = 0;
            Map<String, String> map = new HashMap<>();
            //遍历策略下设备个数，计算总功耗
            for (int j = 0; j < list.size(); j++) {
                PowerInfo powerInfo = list.get(j).get(i);
                Map<String, Integer> strategyPowerHistory = getStrategyPowerHistory(level, powerInfo.getServerPower(), powerInfo.getCpuUsage());
                currentPowerSum += strategyPowerHistory.get("currentPower");
                savePowerSum += strategyPowerHistory.get("savePower");
                estimatePowerSum += strategyPowerHistory.get("estimatePower");
            }
            String collectTime = "";
            if(powerInfoList != null && powerInfoList.size() !=0){
                PowerInfo powerInfo = powerInfoList.get(i);
                if(powerInfo != null) {
                    collectTime = powerInfo.getCollectTime();
                }
            }
            map.put("currentPowerSum", currentPowerSum + "");
            map.put("savePowerSum", savePowerSum + "");
            map.put("estimatePowerSum", estimatePowerSum + "");
            map.put("collectTime", collectTime);
            restultList.add(map);
        }
        return restultList;
    }

    @Override
    public GetAiStrategiesPowerHistoryReply getAiStrategiesPowerHistory(String startTime, String endTime, String strategy) {
        GetAiStrategiesPowerHistoryReply.Builder builder = GetAiStrategiesPowerHistoryReply.newBuilder();
        AiStrategiesPowerAndQosHistoryData.Builder build = AiStrategiesPowerAndQosHistoryData.newBuilder();
        //获取所有打开的策略列表
        List<StrategyDetail> allAutoStrategiesOfOn = strategyManager.getAllAutoStrategiesOfOn();
        if (null == allAutoStrategiesOfOn || allAutoStrategiesOfOn.size() == 0) {
            return builder.build();
        }
        //遍历打开的所有策略
        for (StrategyDetail strategyDetail : allAutoStrategiesOfOn) {
            String controlLevel = strategyDetail.getControlLevel();
            String strategyName = strategyDetail.getStrategyName();
            if (!strategy.equals(strategyName)) {
                continue;
            }
            if (!StringUtil.isEmpty(controlLevel)) {
                //获取当前策略下的所有设备列表
                List<DeviceInfo> deviceInfosList = strategyDetail.getDeviceInfosList();
                if (null == deviceInfosList || deviceInfosList.size() == 0) {
                    logger.error("当前策略下" + strategyName + "没有设备");
                    continue;
                }
                int level = Integer.valueOf(controlLevel);
                //调用计算总功率方法
                List<Map<String, String>> list = getSum(deviceInfosList, startTime, endTime, level);
                for (int i = 0; i < list.size(); i++) {
                    Map<String, String> map = list.get(i);
                    build.addAiStrategiesPowerHistoryData(AiStrategiesPowerHistoryData.newBuilder().setCurrentPower(Integer.valueOf(map.get("currentPowerSum")))
                        .setSavePower(Integer.valueOf(map.get("savePowerSum"))).setEstimatePower(Integer.valueOf(map.get("estimatePowerSum"))).setCollectTime(map.get("collectTime")).build());
                }
            }

        }
        return builder.setData(build.build()).build();
    }

    @Override
    public GetAiPowerHistoryReply getAiPowerHistory(String startTime, String endTime) {
        GetAiPowerHistoryReply.Builder replyBuilder = GetAiPowerHistoryReply.newBuilder();
        AiPowerAndQosHistoryData.Builder builder = AiPowerAndQosHistoryData.newBuilder();
        List<String> list = new ArrayList<>();
        //获取所有服务器历史功耗
        List<PowerByLabel> allServer = powerDataService.getPowerForAi("AllServer", startTime, endTime, 0).getDataList();
        if (null == allServer || allServer.isEmpty() || allServer.size() == 0) {
            return replyBuilder.setErrCode(333).setErrMsg("data error").build();
        }
        List<StrategyDetail> allAutoStrategiesOfOn = strategyManager.getAllAutoStrategiesOfOn();
        if (null == allAutoStrategiesOfOn || allAutoStrategiesOfOn.size() == 0) {
            return replyBuilder.build();
        }
        //遍历ai策略列表，将ai策略添加到集合list中
        for (StrategyDetail strategyDetail : allAutoStrategiesOfOn) {
            list.add(strategyDetail.getStrategyName());
        }
        //获取所有服务器总功耗列表
        List<PowerInfo> infosList = allServer.get(0).getInfosList();
        List<GetAiStrategiesPowerHistoryReply> lists = new ArrayList<>();
        //获取每个策略服务器历史总功耗，添加到集合lists中
        for (int i = 0; i < list.size(); i++) {
            GetAiStrategiesPowerHistoryReply aiStrategiesPowerHistory = getAiStrategiesPowerHistory(startTime, endTime, list.get(i));
            lists.add(aiStrategiesPowerHistory);
        }
        for (int i = 0; i < infosList.size(); i++) {
            int save = 0;
            for (int j = 0; j < lists.size(); j++) {
                GetAiStrategiesPowerHistoryReply getAiStrategiesPowerHistoryReply = lists.get(j);
                List<AiStrategiesPowerHistoryData> aiStrategiesPowerHistoryDataList = getAiStrategiesPowerHistoryReply.getData().getAiStrategiesPowerHistoryDataList();
                if (aiStrategiesPowerHistoryDataList.isEmpty()) {
                    continue;
                }
                AiStrategiesPowerHistoryData aiStrategiesPowerHistoryData = aiStrategiesPowerHistoryDataList.get(i);
                save += aiStrategiesPowerHistoryData.getSavePower();
            }
            PowerInfo powerInfo = infosList.get(i);
            int estimatePower = powerInfo.getSumSerPower() + save;

            builder.addAiPowerHistoryData(AiPowerHistoryData.newBuilder().setCollectTime(powerInfo.getCollectTime()).setCurrentPower(powerInfo.getSumSerPower())
                .setSavePower(save).setEstimatePower(estimatePower).build());
        }
        return replyBuilder.setData(builder).build();
    }

    @Override
    public GetStrategiesNameReply getStrategiesNames() {
        GetStrategiesNameReply.Builder builder = GetStrategiesNameReply.newBuilder();
        StrategiesNames.Builder build = StrategiesNames.newBuilder();
        List<StrategyDetail> allAutoStrategiesOfOn = strategyManager.getAllAutoStrategiesOfOn();
        for (StrategyDetail strategyDetail : allAutoStrategiesOfOn) {
            String strategyName = strategyDetail.getStrategyName();
            build.addStrategiesNames(strategyName);
        }
        return builder.setData(build).build();
    }

    @Override
    public GetModelInferenceReply getModelInference(String taskId, String deviceId) {
        GetModelInferenceReply.Builder builder = GetModelInferenceReply.newBuilder();
        JSONArray jsonArray = null;
        try {
            URI uri = new URIBuilder().setScheme("https")
                .setHost(aiIp)
                //.setPort(443)
                .setPath("/v2/models/inference")
                .setParameter("task_id", taskId)
                .setParameter("data", deviceId)
                .setParameter("token","market_token")
                .build();
            JSONObject jsonObject = HttpUtil.getRequest(uri);
            logger.debug("url == {}", uri.toString());
            if (jsonObject == null) {
                builder.setErrCode(Error.FAILED.getCode()).setErrMsg(Error.FAILED.getMessage());
                logger.error("访问服务器失败,{}", jsonObject);//请求失败
                return builder.build();
            } else if (jsonObject.getInt("err_code") != 0) {
                builder.setErrCode(jsonObject.getInt("err_code")).setErrMsg(jsonObject.getString("err_msg"));
                return builder.build();
            } else {
                jsonArray = jsonObject.getJSONArray("data");
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        if (jsonArray == null) {
            builder.setErrCode(Error.FAILED.getCode()).setErrMsg(Error.FAILED.getMessage());
        } else {
            GetModelInferenceReply.Data.Builder builder1 = GetModelInferenceReply.Data.newBuilder();
            ArrayList<String> list = new ArrayList<>();
            Iterator<Object> iterator = jsonArray.iterator();
            while (iterator.hasNext()) {
                Object next = iterator.next();
                list.add(String.valueOf(next));
            }
            builder1.addAllInferences(list);
            builder.setErrCode(Error.SUCCESS.getCode()).setErrMsg(Error.SUCCESS.getMessage()).setData(builder1);
        }
        return builder.build();
    }

    @Override
    public GetAirSiteBasalReply getAirSiteBasal(GetAirSiteBasalRequest request) {
        GetAirSiteBasalReply.Builder builder = GetAirSiteBasalReply.newBuilder();
        builder.setErrCode(Error.SUCCESS.getCode()).setErrMsg(Error.SUCCESS.getMessage());
        GetAirSiteBasalReply.Data.Builder builder1 = GetAirSiteBasalReply.Data.newBuilder();
        int count = aiDataProviderDao.getCountAirSiteBasal();
        if (count == 0) {
            builder.setData(builder1);
            return builder.build();
        }
        int pageSize = request.getPageSize();
        int pageNum = request.getPageNum();
        List<AirSiteBasalData> list = null;

        if (pageNum <= 0) {
            pageNum = 1;
        }
        if (pageSize <= 0) {
            pageSize = 10;
        }
        int start = (pageNum - 1) * pageSize;
        list = aiDataProviderDao.getCountAirSiteBasalList(start, pageSize);
        builder1.setCurrentPage(pageNum).setTotal(count);
        builder1.addAllAirSiteBasal(list);
        builder.setData(builder1);
        return builder.build();
    }

    @Override
    public GetServerCountReply getServerCount() {
        GetServerCountReply.Builder builder = GetServerCountReply.newBuilder();
        Map<String, String> usedServerAmount = aiDataProviderDao.usedServerAmount();
        if (null == usedServerAmount || usedServerAmount.size() == 0) {
            return builder.build();
        }
        String str = usedServerAmount.get("count");
        int usedCount = Integer.valueOf(str);
        Map<String, String> totalServerAmount = aiDataProviderDao.totalServerAmount();
        if (null == totalServerAmount || totalServerAmount.size() == 0) {
            return builder.build();
        }
        String str2 = totalServerAmount.get("count");
        int totalCount = Integer.valueOf(str2);
        BigDecimal bigDecimaUsed = new BigDecimal(str);
        BigDecimal bigDecimaTotal = new BigDecimal(str2);
        double percentage = bigDecimaUsed.divide(bigDecimaTotal, 2, BigDecimal.ROUND_UP).doubleValue();
        builder.setData(ServerCount.newBuilder().setUsedServerAmount(usedCount).setTotalServerAmount(totalCount).setPercentage(percentage).build());
        return builder.build();
    }

    public void updateStrategyAction(int num) {
        StrategyActionImpl strategyActionDao = new StrategyActionImpl();
        String action1 = "dvfs";
        String action2 = "c_state";
        String action3 = "capping";
        String action4 = "power_off";
        strategyActionDao.deleteByStrategyId(1);
        if (0 == num) {
            logger.debug("新增自动策略动作 策略ID ==1  " + action1);
            strategyActionDao.insert(getStrategyActionEntity(1, action1));
        } else if (1 == num) {

        } else if (2 == num) {
            logger.debug("新增自动策略动作 策略ID ==1  " + action1 + action2);
            strategyActionDao.insert(getStrategyActionEntity(1, action1));
            strategyActionDao.insert(getStrategyActionEntity(1, action2));
        } else if (3 == num) {
            logger.debug("新增自动策略动作 策略ID ==1  " + action1 + action2 + action3 + action4);
            strategyActionDao.insert(getStrategyActionEntity(1, action1));
            strategyActionDao.insert(getStrategyActionEntity(1, action2));
            strategyActionDao.insert(getStrategyActionEntity(1, action3));
            strategyActionDao.insert(getStrategyActionEntity(1, action4));
        }
    }

    private StrategyActionEntity getStrategyActionEntity(int strategyId, String actionName) {
        StrategyActionEntity entity = new StrategyActionEntity();
        StrategyAction.Builder builder2 = StrategyAction.newBuilder();
        entity.setActionName(actionName);
        entity.setFmin("");
        entity.setCapTo("");
        entity.setCapType("");
        StrategyAction.ActionCondition.Builder builder3 = StrategyAction.ActionCondition.newBuilder();
        entity.setState("");
        entity.setMinCPUUsage("");
        entity.setMaxCPUUsage("");
        entity.setMaxPower("");
        entity.setMinPower("");
        entity.setStartTime("");
        entity.setEndTime("");
        entity.setStrategyID(strategyId);

        return entity;
    }

    @Override
    public GetQosCollectInfoReply getQosCurrent(String business) {
        GetQosCollectInfoReply.Builder builder = GetQosCollectInfoReply.newBuilder();
        if (null == business || business.isEmpty()) {
            return builder.build();
        }
        BusinessQosData.Builder builder2 = BusinessQosData.newBuilder();

        Timestamp collect_time = new Timestamp(System.currentTimeMillis());
        builder.setData(builder2.setBusiness(business).setCollectTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(collect_time)).setQos("100"));
        return builder.build();
    }

    @Override
    public GetQosHistoryCollectInfosReply getQosHistory(String business, String startTime, String endTime) {
        long end = DateUtil.dateToMillisecond(endTime);
        long start = DateUtil.dateToMillisecond(startTime);
        GetQosHistoryCollectInfosReply.Builder builder = GetQosHistoryCollectInfosReply.newBuilder();

        long diff =end - start;
        if(diff > diffMax){
            builder.setErrCode(Error.FAILED.getCode()).setErrMsg("时间范围超过限制");
            return builder.build();
        }
        BusinessQosHistoryData.Builder builder2 = BusinessQosHistoryData.newBuilder();
        if (null == business || business.isEmpty()) {
            return builder.build();
        }
        String[] split = business.split(",");
        long l = diff / 30000;
        if (l < 1) {
            return builder.build();
        }
        for (int j = 0; j < split.length; j++) {
            for (int i = 0; i < l-1; i++) {
                String time = DateUtil.millisecondToDate(start + i*30000L);
                builder2.addBusinessQosData(BusinessQosData.newBuilder().setBusiness(split[j]).setCollectTime(time).setQos("100").build());
            }
        }
        return builder.setData(builder2.build()).build();
    }

    @Override
    public GetCfdCalculationReply getCfdCalculation(GetCfdCalculationRequest request) {
        GetCfdCalculationReply.Builder builder = GetCfdCalculationReply.newBuilder();
        String deviceSn = request.getDeviceSn();
        if (StringUtil.isEmpty(deviceSn)) {
            return builder.setErrCode(701).setErrMsg("服务器sn不能为空").build();
        }
        int count = request.getCount();
        if (count <= 0) {
            return builder.setErrCode(702).setErrMsg("计算数量必须大于0").build();
        }
        List<Map<String, String>> maps = aiDataProviderDao.listPowerInfoByCondition(deviceSn, count);
        if (null == maps || maps.size() == 0) {
            return builder.build();
        }
        for (int i = 0;i < maps.size(); i++) {
            Map<String, String> map = maps.get(i);
            String serverPower = StringUtil.nullToZero(map.get("server_power"));
            String inletTemp = StringUtil.nullToZero(map.get("inlet_temp"));
            String collectTime = TimeConvertUtil.mysqlTimeSubstring(map.get("collect_time"));
            Integer result = cfdCalculation(serverPower, inletTemp);
            builder.addData(CfdCalculation.newBuilder().setCollectTime(collectTime).setDeviceSn(deviceSn).setInletTemp(new BigDecimal(inletTemp).intValue()).setPower(new BigDecimal(serverPower).intValue())
                .setResultOutletTemp(result).build());
        }
        return builder.build();
    }

    @Override
    public GetCfdDataEnhancementReply getCfdDataEnhancement(GetCfdDataEnhancementRequest request) {
        GetCfdDataEnhancementReply.Builder builder = GetCfdDataEnhancementReply.newBuilder();
        String deviceSn = request.getDeviceSn();
        BigDecimal avg = new BigDecimal(2);
        int size = 0;
        if (StringUtil.isEmpty(deviceSn)) {
            return builder.setErrCode(701).setErrMsg("服务器sn不能为空").build();
        }
        int count = request.getCount();
        if (count % 2 != 0) {
            count = count -1;
        }
        if (count <= 0) {
            return builder.setErrCode(702).setErrMsg("计算数量必须大于0").build();
        }
        List<Map<String, String>> maps = aiDataProviderDao.listPowerInfoByCondition(deviceSn, count);
        if (null == maps || maps.size() == 0) {
            return builder.build();
        }
        size = maps.size();
        if (size % 2 != 0) {
            size = size -1;
        }
        if (size == 0) {
            return builder.build();
        }
        for (int i = 0; i <size; i += 2) {
            Map<String, String> map = maps.get(i);
            String serverPower = StringUtil.nullToZero(map.get("server_power"));
            String inletTemp = StringUtil.nullToZero(map.get("inlet_temp"));
            String outletTemp = StringUtil.nullToZero(map.get("outlet_temp"));
            String collectTime = TimeConvertUtil.mysqlTimeSubstring(map.get("collect_time"));
            Integer result = cfdCalculation(serverPower, inletTemp);
            Map<String, String> map2 = maps.get(i + 1);
            String serverPower2 = StringUtil.nullToZero(map2.get("server_power"));
            String inletTemp2 = StringUtil.nullToZero(map2.get("inlet_temp"));
            String outletTemp2 = StringUtil.nullToZero(map2.get("outlet_temp"));
            Integer result2 = cfdCalculation(serverPower2, inletTemp2);
            if (Math.abs((new BigDecimal(outletTemp).intValue() - result)) <= cfdcoef && Math.abs((new BigDecimal(outletTemp2).intValue() - result2)) <= cfdcoef) {
                BigDecimal temp = new BigDecimal(inletTemp).add(new BigDecimal(inletTemp2));
                BigDecimal resultInletTemp = temp.divide(avg, BigDecimal.ROUND_HALF_UP);
                BigDecimal power = new BigDecimal(serverPower).add(new BigDecimal(serverPower2));
                BigDecimal resultPower = power.divide(avg, BigDecimal.ROUND_HALF_UP);
                Integer resultOutletTemp = resultPower.divide(new BigDecimal(100),BigDecimal.ROUND_HALF_UP).add(resultInletTemp).intValue();
                builder.addData(CfdDataEnhancement.newBuilder().setDeviceSn(deviceSn).setCollectTime(collectTime).setResultInletTemp(resultInletTemp.intValue()).setResultPower(resultPower.intValue())
                    .setResultOutletTemp(resultOutletTemp).build());
            }
        }
        return builder.build();
    }


    public List<BusinessQosData> getQosList(String businessName, String startTime, String endTime) {
        ArrayList<BusinessQosData> list1 = new ArrayList<>();
        long milInter = 30 * 1000;
        int count = (int) ((dateToMillisecond(endTime) - dateToMillisecond(startTime)) / milInter);
        count = (count == 0 ? 1 : count);
        for (int i = 0; i < count; i++) {
            BusinessQosData.Builder builder = BusinessQosData.newBuilder();
            builder.setBusiness(businessName);
            builder.setQos("100").setCollectTime(millisecondToDate(dateToMillisecond(startTime)+(i*milInter)));
            list1.add(builder.build());
        }

        return list1;
    }


    private Integer cfdCalculation(String serverPower, String inletTemp) {
        BigDecimal power = new BigDecimal(serverPower);
        BigDecimal temp = new BigDecimal(inletTemp);
        Integer result = power.divide(new BigDecimal(100),BigDecimal.ROUND_HALF_UP).add(temp).intValue();
        return result;
    }

    private Double getAvg(List<BigDecimal> list) {
        if (null == list || list.isEmpty() || list.size() == 0) {
            return 0.0;
        }
        BigDecimal sum = new BigDecimal(0);
        for (int i = 0; i < list.size(); i++) {
            sum = sum.add(list.get(i));
        }
        double b = sum.divide(new BigDecimal(list.size()), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
        return b;
    }

}
